#pragma once

#include "noncopyable.h"
#include "Timestamp.h"   // 时间戳类，用于记录事件发生的时间

#include <functional>
#include <memory>

class EventLoop;  // 前向声明，表示Channel将与EventLoop类有关联

/**
 * 理清楚  EventLoop、Channel、Poller之间的关系   《= Reactor模型上对应 Demultiplex
 * Channel 理解为通道，封装了sockfd和其感兴趣的event，如EPOLLIN、EPOLLOUT事件
 * 还绑定了poller返回的具体事件
 */ 
class Channel : noncopyable
{
public:
    using EventCallback = std::function<void()>;  // 定义事件回调的函数类型
    using ReadEventCallback = std::function<void(Timestamp)>;  // 读事件回调，带时间戳参数

    Channel(EventLoop *loop, int fd);  // 构造函数，需要事件循环和文件描述符
    ~Channel();  // 析构函数

    // 根据poller的通知处理事件
    void handleEvent(Timestamp receiveTime);

    // 设置各种事件的回调函数
    void setReadCallback(ReadEventCallback cb) { readCallback_ = std::move(cb); } // 传右值避免不必要的拷贝
    void setWriteCallback(EventCallback cb) { writeCallback_ = std::move(cb); }
    void setCloseCallback(EventCallback cb) { closeCallback_ = std::move(cb); }
    void setErrorCallback(EventCallback cb) { errorCallback_ = std::move(cb); }

    // 绑定channel到一个存在的对象，防止channel还在使用时对象被销毁
    void tie(const std::shared_ptr<void>&);

    // 获取和设置fd及其事件状态的方法
    int fd() const { return fd_; }
    int events() const { return events_; }
    int set_revents(int revt) { revents_ = revt; }

    // 设置fd相应的事件状态
    void enableReading() { events_ |= kReadEvent; update(); }  // 让 events_ 有读事件; 
    void disableReading() { events_ &= ~kReadEvent; update(); }
    void enableWriting() { events_ |= kWriteEvent; update(); }
    void disableWriting() { events_ &= ~kWriteEvent; update(); }
    void disableAll() { events_ = kNoneEvent; update(); }

    // 返回fd当前的事件状态
    bool isNoneEvent() const { return events_ == kNoneEvent; }
    bool isWriting() const { return events_ & kWriteEvent; } // 对应位为1，结果才为1；
    bool isReading() const { return events_ & kReadEvent; }

    // 管理poller中的索引 
    int index() { return index_; } // 用于获取 Channel 当前在 Poller 中的索引
    void set_index(int idx) { index_ = idx; } // 用于设置 Channel 在 Poller 中的索引

    // 获取此channel属于的EventLoop
    EventLoop* ownerLoop() { return loop_; }
    void remove(); // 从EventLoop中移除自己
private:
    void update();  // 通知EventLoop更新poller的注册信息
    void handleEventWithGuard(Timestamp receiveTime);  // 安全处理事件，防止在处理过程中Channel被销毁

    // 静态常量定义事件类型
    static const int kNoneEvent;
    static const int kReadEvent;
    static const int kWriteEvent;

    EventLoop *loop_;         // 此channel所属的事件循环
    const int fd_;            // 监听的文件描述符
    int events_;              // 注册的事件类型  (struct epoll_event *event 结构体中有 events和data联合体,
                              //                 events: EPOLLIN / EPOLLOUT / EPOLLERR)
    int revents_;             // 实际发生的事件类型, 看epoll_wait()
    int index_;               // 在poller中的索引（状态）, 初始化为-1, channel未添加到poller中; 

    std::weak_ptr<void> tie_; // 弱引用，用于管理对象生命周期
    bool tied_;               // 标识是否已经与某个对象绑定

    // 回调函数，具体处理不同类型的事件
    ReadEventCallback readCallback_;
    EventCallback writeCallback_;
    EventCallback closeCallback_;
    EventCallback errorCallback_;
};






















